/* Sintaxis JFlex */
/* Inclusiones de codigo */
package Lexico;

import TablaDeSimbolos.*;
import GestorDeErrores.*;
import java.io.FileReader;
import java.util.ArrayList;

/* Declaraciones */
%%

%class Lexico
%unicode
%cup
%public
%line
%column
/* Token que retornarÃ¡ con el fin de fichero */
%eofval{
  return new Token(TipoToken.EOF.ordinal());
%eofval}

/* Codigo empotrado */
%{
  
  StringBuffer string = new StringBuffer();
  
  private Token creaToken(TipoToken type, Object value) {
	ArrayList<Object> atributos = new ArrayList<Object>();
	if (type == TipoToken.SEPARADOR){
		atributos.add((TipoSeparadores)value);
	} else if (type == TipoToken.ABREPAREN 	||
		   type == TipoToken.CIERRAPAREN	||
		   type == TipoToken.ABRECORCHETE 	||
		   type == TipoToken.CIERRACORCHETE){
		// No tiene atributos
	} else if (type == TipoToken.OPER_ARIT){
		atributos.add((TipoOperadoresAritmeticos)value);
	} else if (type == TipoToken.OPER_RELACIONAL){
		atributos.add((TipoOperadoresRelacionales)value);
	}else if (type == TipoToken.IDENTIFICADOR){
		if (tablaSimbolos.esReservada((String)value)){
			type = TipoToken.PAL_RES;
		}
		atributos = tablaSimbolos.insertaIdentificador((String)value);
	} else if (type == TipoToken.PUNTERO) {
		atributos = tablaSimbolos.insertaIdentificador((String)value);
	} else if (type == TipoToken.LITERAL_ENTERO){
		atributos.add(new Integer((Integer)value)); 		
	} else if (type == TipoToken.LITERAL_REAL){
		atributos.add(new Double((Double)value));
	} else if (type == TipoToken.LITERAL_CARACTER){
		atributos.add(new Character((Character)value));
	} else if (type == TipoToken.LITERAL_CADENA){
		atributos.add(new String((String)value));	
	} 
	
    return new Token(type.ordinal(), yyline, yycolumn, atributos);
  }
%}

/* Expresiones Regulares */

letra           = [A-Za-z]
digito          = [0-9]
inttochar       = \# {digito}{digito}{digito} |\# {digito}{digito} |\# {digito} 
alfanumerico    = {letra}|{digito}
caracter		= \'([^'])?\'
cadena			= \'([^'])*\'
identificador   = {letra}({alfanumerico}| \_)*
entero          = {digito}+
numeroE			= \E | \e | \E\+ |\E\- | \e\+ | \e\-
real            = {digito}+\.{digito}+({numeroE}{digito}+)?
idError         = {digito}+({identificador})
llaveIzq        = \{
llaveDer        = \}
comentarioIni   = \(\* 
comentarioFin   = \*\)
todoMenosLlave  = [^}]
todoMenosParen  = [^)]
cuerpoComentario1= {todoMenosLlave}*
cuerpoComentario2= {todoMenosParen}* 
comentario      = {llaveIzq}{cuerpoComentario1}{llaveDer} | {comentarioIni}{cuerpoComentario2}{comentarioFin}
espacio         = [ \n\t\r]


%state STRING

/* Acciones semÃ¡nticas asociadas a patrones */
%%

"*"             { return creaToken(TipoToken.OPER_ARIT, TipoOperadoresAritmeticos.POR); }
"+"             { return creaToken(TipoToken.OPER_ARIT, TipoOperadoresAritmeticos.MAS); }
"-"             { return creaToken(TipoToken.OPER_ARIT, TipoOperadoresAritmeticos.MENOS); }
"/"             { return creaToken(TipoToken.OPER_ARIT, TipoOperadoresAritmeticos.DIVIDE); }
";"             { return creaToken(TipoToken.SEPARADOR, TipoSeparadores.PUNTOYCOMA); }
","             { return creaToken(TipoToken.SEPARADOR, TipoSeparadores.COMA); }
"("             { return creaToken(TipoToken.ABREPAREN, yytext()); }
")"             { return creaToken(TipoToken.CIERRAPAREN, yytext()); }
"["             { return creaToken(TipoToken.ABRECORCHETE, yytext()); }
"]"             { return creaToken(TipoToken.CIERRACORCHETE, yytext()); }
// Estos dos de debajo son iguales que los corchetes
"(."            { return creaToken(TipoToken.ABRECORCHETE, yytext()); }
".)"            { return creaToken(TipoToken.CIERRACORCHETE, yytext()); }
"and"           { return creaToken(TipoToken.OPER_LOGICO, TipoOperadoresLogicos.AND); }
"or"            { return creaToken(TipoToken.OPER_LOGICO, TipoOperadoresLogicos.OR); }
"not"           { return creaToken(TipoToken.OPER_LOGICO, TipoOperadoresLogicos.NOT); }
"xor"           { return creaToken(TipoToken.OPER_LOGICO, TipoOperadoresLogicos.XOR); }
"shl"           { return creaToken(TipoToken.OPER_LOGICO, TipoOperadoresLogicos.DESP_IZQ); }
"shr"           { return creaToken(TipoToken.OPER_LOGICO, TipoOperadoresLogicos.DESP_DER); }
"="             { return creaToken(TipoToken.OPER_RELACIONAL, TipoOperadoresRelacionales.IGUAL); }
"<"             { return creaToken(TipoToken.OPER_RELACIONAL, TipoOperadoresRelacionales.MENOR); }
">"             { return creaToken(TipoToken.OPER_RELACIONAL, TipoOperadoresRelacionales.MAYOR); }
"<="            { return creaToken(TipoToken.OPER_RELACIONAL, TipoOperadoresRelacionales.MENOROIGUAL); }
">="            { return creaToken(TipoToken.OPER_RELACIONAL, TipoOperadoresRelacionales.MAYOROIGUAL); }
"!="            { return creaToken(TipoToken.OPER_RELACIONAL, TipoOperadoresRelacionales.DISTINTO); }
":"             { return creaToken(TipoToken.SEPARADOR, TipoSeparadores.DOSPUNTOS); }
":="            { return creaToken(TipoToken.OPER_ASIGNACION, yytext()); }
"."             { return creaToken(TipoToken.SEPARADOR, TipoSeparadores.PUNTO); }
"^"				{ return creaToken(TipoToken.PUNTERO, yytext()); }
"$"				{ return creaToken(TipoToken.HEXADECIMAL, yytext()); }
{inttochar}     { 
        	      int num = Integer.parseInt(yytext().substring(1));
        	      if ((num<=255) && num>=0){
	        	      Character ch = new Character ((char) num);
    	    	      return creaToken(TipoToken.LITERAL_CARACTER,ch);
    	    	  }
        	      else gestor.insertaError(new GestorDeErrores.TError(Errores.ID_CHAR_ERROR,yytext(),yyline,yycolumn));
        		}
{identificador} { return creaToken(TipoToken.IDENTIFICADOR, yytext()); }
{entero}        { return creaToken(TipoToken.LITERAL_ENTERO, new Integer(yytext())); }
{real}          { return creaToken(TipoToken.LITERAL_REAL, new Double(yytext())); }
{caracter}		{ return creaToken(TipoToken.LITERAL_CARACTER, new Character(yytext().charAt(1)));}
{cadena}		{ return creaToken(TipoToken.LITERAL_CADENA, new String(yytext().substring(1,yytext().length()-1)));}
{idError}       {gestor.insertaError(new GestorDeErrores.TError(Errores.LEXICO_ID_ERROR,yytext(),yyline,yycolumn));
				/*System.out.println("Error construccion identificador: '" + yytext() + "' linea: " + yyline + ", columna: " + yychar);*/ }
{comentario}    { /* En la versiÃ³n final ignorarÃ¡ comentarios */ /*System.out.println("Comentario reconocido: " + yytext());*/ }
{espacio}       { /* Ignora espacios. */ }
.               { /*System.out.println("Caracter ilegal, '" + yytext() + "' linea: " + yyline + ", columna: " + yychar);*/ 
				  gestor.insertaError(new GestorDeErrores.TError(Errores.LEXICO_CARACTER_NO_VALIDO,yytext(),yyline,yycolumn)); 
				}
